<template>
  <div>
    <span v-if="labelOnly">{{label}}</span>
    <treeselect
      v-show="!labelOnly"
      class="tree-select"
      @select="handleSelect"
      @deselect="handleCancelSelect"
      :style="selectStyle"
      v-model="value"
      :multiple="multiple"
      :disable-branch-nodes="disableBranchNodes"
      :placeholder="placeholder"
      :options="options"
      :disabled="disabled"
      :clearable="clearable"
      noOptionsText="暂无数据"
      noChildrenText="无子节点"
      noResultsText="未搜索到内容"
    >
      <div
        slot="value-label"
        slot-scope="{ node }"
      >{{ customLabel ? node.raw.customLabel : node.raw.label }}</div>
    </treeselect>
  </div>
</template>

<script>
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'

export default {
  // register the component
  components: { Treeselect },
  props: {
    placeholder: {
      type: String,
      default: '请选择，可输入文字搜索'
    },
    // 样式
    selectStyle: {
      type: Object,
      default: () => {
        return {}
      }
    },
    labelOnly: {
      type: Boolean,
      default: false
    },
    customLabel: {
      type: Boolean,
      default: false
    },
    // 禁选
    disabled: {
      type: Boolean,
      default: false
    },
    // 多选框
    multiple: {
      type: Boolean,
      default: false
    },
    disableBranchNodes: {
      type: Boolean,
      default: false
    },
    // 是否可清空
    clearable: {
      type: Boolean,
      default: false
    },
    // 数据
    options: {
      type: Array,
      required: true
    },
    // 选择值
    selectValue: [String, Array] // 多选时为Array
  },
  watch: {
    selectValue(n, o) {
      if (n !== '' || n !== null) {
        this.value = n
      }
    },
    value(value) {
      let valueDetail = []
      const interval = setInterval(() => { // 由于数据源的获取比prop的值延迟一些，所以用定时器先判断一下数据源，数据源有值的时候才遍历
        if (this.options && this.options.length) {
          clearInterval(interval)
          if (value) {
            this.getValueDetail(value, valueDetail)
            this.getLabel(valueDetail)
          }
          this.$emit('valueChange', value, valueDetail)
        }
      }, 100)
    }
  },
  created() {
    if (this.selectValue) {
      this.value = this.selectValue
    }
  },
  data() {
    return {
      value: null
    }
  },
  methods: {
    handleCancelSelect(node, id) {
      this.$emit('cancelSelect', node)
    },
    handleSelect(node, id) {
      this.$emit('treeSelect', node)
    },
    reset() {
      this.value = null
    },
    getValueDetail(value, valueDetail) {
      // 获取选项详情
      if (value) {
        if (this.multiple) {
          value.forEach(valueItem => {
            this.findDetail(this.options, valueItem, valueDetail)
          })
        } else {
          this.findDetail(this.options, value, valueDetail)
        }
      }
    },
    findDetail(array, valueItem, valueDetail) {
      array.forEach(data => {
        if (data.key === valueItem) {
          valueDetail.push(data)
        } else {
          if (data.children && data.children.length) {
            this.findDetail(data.children, valueItem, valueDetail)
          }
        }
      })
    },
    getLabel(valueDetail) {
      this.label = ''
      if (valueDetail && valueDetail.length) {
        if (this.multiple) {
          const list = []
          valueDetail.forEach(item => {
            list.push(item.customLabel || item.label)
          })
          this.label = list.join(',')
        } else {
          this.label = valueDetail[0].customLabel || valueDetail[0].label
        }
      }
    }
  }
}
</script>

<style scoped>
.vue-treeselect {
  line-height: 24px;
}
.vue-treeselect__multi-value-label {
  line-height: 24px;
}
</style>
